package com.truedian.wg.components.organism.dialog.internal

import com.tencent.kuikly.core.base.Animation
import com.tencent.kuikly.core.base.Color
import com.tencent.kuikly.core.base.ComposeAttr
import com.tencent.kuikly.core.base.ComposeEvent
import com.tencent.kuikly.core.base.ComposeView
import com.tencent.kuikly.core.base.Scale
import com.tencent.kuikly.core.base.Translate
import com.tencent.kuikly.core.base.ViewBuilder
import com.tencent.kuikly.core.base.ViewContainer
import com.tencent.kuikly.core.directives.velse
import com.tencent.kuikly.core.directives.vif
import com.tencent.kuikly.core.layout.FlexDirection
import com.tencent.kuikly.core.reactive.handler.observable
import com.tencent.kuikly.core.views.View

/**
 * 弹窗项视图组件
 *
 * 该组件负责渲染单个弹窗项，包括弹窗的背景遮罩层和内容区域。
 * 根据弹窗位置类型（中心或底部）提供不同的动画和布局效果。
 *
 * ## 主要功能
 * - 渲染弹窗的背景遮罩层
 * - 根据弹窗位置类型提供不同的布局和动画效果
 * - 处理弹窗的显示和隐藏动画
 * - 支持点击遮罩层关闭弹窗的交互
 *
 * ## 技术实现
 * - 使用响应式状态管理动画状态
 * - 根据[DialogPosition]类型提供不同的布局和动画效果
 * - 中心弹窗使用缩放动画效果
 * - 底部弹窗使用上滑动画效果
 * - 监听动画完成事件，触发弹窗关闭回调
 *
 * ## 动画效果
 * - 显示：背景从透明到半透明，内容根据位置类型执行相应动画
 * - 隐藏：背景从半透明到透明，内容根据位置类型执行相应动画
 * - 中心弹窗：缩放动画（0.9 -> 1.0）
 * - 底部弹窗：平移动画（底部 -> 当前位置）
 */
class InternalDialogItemView : ComposeView<DialogItemAttr, DialogItemEvent>() {

    /**
     * 动画状态标志
     * 
     * true 表示弹窗处于显示状态
     * false 表示弹窗处于隐藏状态
     */
     var animated: Boolean by observable(false)

    /**
     * 视图布局完成后的回调
     * 
     * 在此方法中，将动画状态设置为显示状态，触发弹窗的显示动画
     */
    override fun viewDidLayout() {
        super.viewDidLayout()
        animated = true
    }

    /**
     * 构建组件视图
     * 
     * 创建弹窗的背景遮罩层和内容区域，根据弹窗位置类型提供不同的布局和动画效果
     *
     * @return 视图构建器函数
     */
    override fun body(): ViewBuilder {
        val ctx = this
        ref {
            ctx.attr.dialogStackItem?.internalDialogItemView = it.view
        }
        return {
            View {
                attr {
                    width(pagerData.pageViewWidth)
                    height(pagerData.pageViewHeight)

                    if (ctx.animated) {
                        backgroundColor(
                            ctx.attr.dialogStackItem?.dialogUiConfig?.maskLayerColor
                                ?: Color(0x90000000)
                        )
                    } else {
                        backgroundColor(Color.TRANSPARENT)
                    }

                    animation(
                        Animation.linear(
                            ctx.attr.dialogStackItem?.dialogUiConfig?.animationTime
                                ?: 0.1f
                        ), ctx.animated
                    )

                }

                event {
                    if (ctx.attr.dialogStackItem?.dialogUiConfig?.isCanClickBackground == false) {
                        click {
                            if (ctx.attr.dialogStackItem?.dialogUiConfig?.isCanCancelOutSide == true) {
                                ctx.animated = false
                            }
                        }
                    }
                }

                vif({ ctx.attr.dialogStackItem?.dialogPosition == DialogPosition.Center }) {
                    View {
                        attr {
                            absolutePositionAllZero()
                            allCenter()
                            opacity(0f)
                            if (ctx.animated) {
                                opacity(1f)
                                transform(Scale(1f, 1f))
                            } else {
                                transform(Scale(0.9f, 0.9f))
                            }


                            animation(
                                Animation.linear(
                                    ctx.attr.dialogStackItem?.dialogUiConfig?.animationTime
                                        ?: 0.1f
                                ), ctx.animated
                            )
                        }

                        event {
                            animationCompletion {
                                if (!ctx.animated) {
                                    ctx.event.onCancelAnimFinish?.invoke()
                                }
                            }
                        }

                        val dialogComponent = ctx.attr.dialogStackItem?.dialogComponent

                        if (dialogComponent != null) {
                            View {
                                dialogComponent()
                                event {
                                    click {}
                                }
                            }
                        }
                    }
                }
                velse {
                    View {
                        attr {
                            positionAbsolute()
                            left(0f)
                            right(0f)
                            bottom(0f)
                            flexDirection(FlexDirection.COLUMN_REVERSE)
                            if (ctx.animated) {
                                transform(Translate(0f, 0f))
                            } else {
                                transform(Translate(0f, 1f))
                            }
                            animation(
                                Animation.linear(
                                    ctx.attr.dialogStackItem?.dialogUiConfig?.animationTime
                                        ?: 0.1f
                                ), ctx.animated
                            )
                        }

                        event {
                            animationCompletion {
                                if (!ctx.animated) {
                                    ctx.event.onCancelAnimFinish?.invoke()
                                }
                            }
                        }

                        val dialogComponent = ctx.attr.dialogStackItem?.dialogComponent

                        if (dialogComponent != null) {
                            View {
                                dialogComponent()
                                event {
                                    click {}
                                }
                            }
                        }
                    }
                }

            }
        }
    }

    /**
     * 创建组件属性对象
     *
     * @return 新的[DialogItemAttr]实例
     */
    override fun createAttr() = DialogItemAttr()

    /**
     * 创建组件事件对象
     *
     * @return 新的[DialogItemEvent]实例
     */
    override fun createEvent() = DialogItemEvent()
}

/**
 * 弹窗项属性类
 *
 * 包含弹窗项的配置信息
 */
class DialogItemAttr : ComposeAttr() {
    /**
     * 弹窗堆栈项
     * 
     * 包含弹窗的位置、UI配置和内容组件等信息
     */
    var dialogStackItem: DialogStackItem? = null
}

/**
 * 弹窗项事件类
 *
 * 包含弹窗项的事件回调
 */
class DialogItemEvent : ComposeEvent() {
    /**
     * 取消动画完成回调
     * 
     * 当弹窗的隐藏动画完成时触发，用于通知容器组件关闭弹窗
     */
    var onCancelAnimFinish: (() -> Unit)? = null
}

/**
 * 弹窗项视图DSL构建函数
 *
 * 提供一个便捷的DSL方式来添加弹窗项视图到视图容器中
 *
 * @param init 初始化弹窗项视图的lambda表达式
 */
internal fun ViewContainer<*, *>.DialogItemView(init: InternalDialogItemView.() -> Unit) {
    addChild(InternalDialogItemView(), init)
}